package server;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.sql.*;
import java.util.Vector;

import javax.media.jai.JAI;

import client.Util;

import com.sun.media.jai.codec.ImageCodec;

public class UploadServiceImpl extends java.rmi.server.UnicastRemoteObject implements UploadService {
	private String databaseServer;
	private String rmiServerName;
	private String imagesFolder;
	private Process rmiRegistry;
	
	public UploadServiceImpl(File configFile) throws RemoteException {
		super(1099);
		
		processFile(configFile);
		
		System.getProperties().put("java.security.policy", "client.policy");
		System.getProperties().put("java.rmi.server.hostname", rmiServerName);
		
		if(databaseServer == null | rmiServerName == null | imagesFolder == null){
			System.out.println("Incomplete configuration file, could not start server!");
			System.exit(1);
		}else{
			System.out.println("Configuration Complete");
			/* Boot registry */
			System.out.println("Booting the registry");
			try{
				Registry reg = LocateRegistry.createRegistry(1099);
				/* Bind service to registry */
				reg.rebind("rmi://" + rmiServerName, this);
			}catch(Exception e){
				e.printStackTrace();
				System.err.println("Could not boot RMI registry");
				System.exit(1);
			}	
		}
		
		System.out.println("System Now Booted");
	}

	private void processFile(File config){
		/* First check file exists */
		if(!config.exists()){
			System.err.println("Could not file configuration file .config, please ensure .config is located in the install directory.");
			System.exit(1);
		}else{	
			System.out.println("Reading configuration file");
			
			/* Open text file */
			try {
				BufferedReader read = new BufferedReader(new FileReader(config));
				/* Read until we find match to user name */
				String currentLine;
				while((currentLine = read.readLine()) != null){
					if(currentLine.contains("#")){
						
					}else{
						String[] configOption = currentLine.split("=");
						
						/* Figure out which option it is */
						if(configOption[0].equalsIgnoreCase("mysql-server-host")){
							System.out.println("Configuring MySQL Host");
							databaseServer = configOption[1];
						}else if(configOption[0].equalsIgnoreCase("rmi-registry-host")){
							System.out.println("Configuring Registry Host");
							rmiServerName = configOption[1];
						}else if(configOption[0].equalsIgnoreCase("image-file-path")){
							System.out.println("Configuring Image Output Folder");
							imagesFolder = configOption[1];
						}
					}
				}
				read.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public Vector<ImageResult> search(String searchString)throws RemoteException {
		String databaseLocation = "jdbc:mysql://" + databaseServer + "/imagedatabase";
		Connection databaseCon = null;
		Vector<ImageResult> returnVector = new Vector<ImageResult>();
		ResultSet results;
		
		/* Register the MySQL database driver */
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			
			databaseCon = DriverManager.getConnection(databaseLocation, "imageupload", "imageupload");
						
			/* Create the Statement and exectue it */
			Statement uploadStatement = databaseCon.createStatement();
			System.out.println("Connected to database");
			results = uploadStatement.executeQuery("SELECT imageTitle, imageDescription, imageFileSize, imageCompression, compressImageLocation FROM images WHERE imageKeywords LIKE '%" + searchString  + "%'");
			
			/** Add the results to the Vector */
			while(results.next()){
				/* Build thumnail of the image */
				File filePath = new File(imagesFolder + results.getString("compressImageLocation"));

				byte[] file = Util.fileToByteArray(filePath);
				
				returnVector.add(new ImageResult(results.getString("imageTitle"), results.getString("imageDescription"), results.getString("imageFileSize"),results.getString("imageCompression"), file));
			}
			
			databaseCon.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return returnVector;
	}
	
	public void uploadImage(ImageUpload i) throws RemoteException {
		System.out.println("Uploading Image");
		String databaseLocation = "jdbc:mysql://"+databaseServer+"/imagedatabase";
		Connection databaseCon = null;
		System.out.println("Connecting to: " + databaseLocation);
		/* Register the MySQL database driver */
		try {
			
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			
			databaseCon = DriverManager.getConnection(databaseLocation, "imageupload", "imageupload");
			
			System.out.println("Connected to database: " + databaseCon);
			
			/* Create the Statement and exectue it */
			Statement uploadStatement = databaseCon.createStatement();
			uploadStatement.execute(i.insert());
			
			writeFilesToDisk(i);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void writeFilesToDisk(ImageUpload i){
		try{
			BufferedOutputStream original = new BufferedOutputStream(new FileOutputStream(imagesFolder+ i.getOriginalFileName()));
			BufferedOutputStream compressed = new BufferedOutputStream(new FileOutputStream(imagesFolder + i.getCompressedFileName()));

			original.write(i.getOriginalImage());
			compressed.write(i.getCompressedImage());
		}catch( Exception e ){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		System.out.println("Starting upload Service");
		
		System.getProperties().put("java.security.policy", "client.policy");
		System.getProperties().put("java.rmi.server.hostname", "test-server.selfip.com");
		
		System.setSecurityManager(new java.rmi.RMISecurityManager());
		try {
			UploadService upload = new UploadServiceImpl(new File(".config"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
